package com.eques.demo

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.TextureView
import android.view.View
import android.widget.FrameLayout
import android.widget.Toast
import com.eques.base.BaseActivity
import com.eques.bean.Mjpeg
import com.eques.database.DevList
import com.eques.database.dao.DevListDao
import com.eques.database.dao.ShaowDao
import com.eques.event.EventTotalThread
import com.eques.icvss.core.module.user.BuddyType
import com.eques.icvss.utils.ELog
import com.eques.impl.ImgDataListener
import com.eques.service.DoorBellService
import com.eques.util.BaseAppApplication
import com.eques.util.Config
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.commons.lang3.StringUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.ref.WeakReference
import java.util.concurrent.Executors
import kotlin.math.min

/**
 * 视频通话界面
 * @author: yc
 * @date: 2025/4/8 11:07
 */
class VideoCallActivity : BaseActivity(),
    SurfaceHolder.Callback,
    ImgDataListener {

    private val TAG: String = VideoCallActivity::class.java.simpleName

    companion object {
        private var wakeupCount = 0 // 唤醒轮询次数，最多60次
        private const val REQUEST_AWAKEN = 1 // 唤醒设备
        private const val FIRST_FRAME_COME = 3 // 第一帧动画
        private const val CLOSE_VIDEO = 4 // 挂断会话
        private const val CONNECTION_TIMEOUT = 5 // 连接超时
        private const val AUTO_HANGUP = 6 // 自动挂断
    }

    private lateinit var devDao: DevListDao
    private lateinit var shaowDao: ShaowDao

    private lateinit var devId: String
    private lateinit var userName: String

    private lateinit var surfaceView: SurfaceView
    private lateinit var textureView: TextureView
    private lateinit var frRoot: FrameLayout
    private lateinit var loadingLayout: View // 加载布局
    private lateinit var controlPanel: View // 控制按钮面板

    private var surfaceHolder: SurfaceHolder? = null
    private var paint: Paint? = null // 画笔
    private var matrix: Matrix? = null // 用于图片变换的矩阵
    private var canvas: Canvas? = null // 画布
    private var surfaceThread: SurfaceThread? = null
    private var mjpeg: Mjpeg? = null // 图片临时存储介质
    private var isBitmapData = false
    private var mCreateHolder: SurfaceHolder? = null
    private var isWakeUp = true
    private var online = false // 记录设备进入时候的状态
    private var isHasCall = false
    private var devRole = 0 // 设备类型
    private var uid: String? = null
    private var channelId = -1
    private var devState = 0 // 设备是否在线
    private var devInfo: DevList? = null
    private var videoIsPlaying = false
    private var isRecordAudio = false // 是否录制音频
    private var isPlayAudio = true // 是否播放音频
    private var isHangUp = false

    // 视频源尺寸
    private var videoWidth = 480f
    private var videoHeight = 864f
    // 显示区域尺寸
    private var displayWidth = 0f
    private var displayHeight = 0f
    // 缩放后的图片尺寸
    private var scaledWidth = 0f
    private var scaledHeight = 0f
    // 绘制偏移量（用于居中）
    private var offsetX = 0f
    private var offsetY = 0f

    private var degree = 90f

    private val mHandler = MyHandler(WeakReference(this))
    private var isRunDraw = true

    inner class MyHandler(val wrActivity: WeakReference<VideoCallActivity>) :
        Handler(Looper.getMainLooper()) {

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val activity = wrActivity.get() ?: return

            when (msg.what) {
                FIRST_FRAME_COME -> {
                    ELog.showToast(activity, "视频已经接通", Toast.LENGTH_SHORT)
                    videoIsPlaying = true
                    // 隐藏加载框，显示控制按钮
                    activity.showControls()
                    // 2分钟后自动挂断
                    sendEmptyMessageDelayed(AUTO_HANGUP, 120000)
                }

                REQUEST_AWAKEN -> {
                    if (wakeupCount <= 60) {
                        DoorBellService.icvss?.equesT1WakeUpScreen(activity.devId, 2, 1)
                        sendEmptyMessageDelayed(REQUEST_AWAKEN, 500)
                        wakeupCount++
                    } else {
                        removeMessages(REQUEST_AWAKEN)
                    }
                }

                CLOSE_VIDEO -> {
                    closeAll()
                }

                CONNECTION_TIMEOUT -> {
                    // 30秒内未接通，主动挂断
                    if (!activity.videoIsPlaying) {
                        ELog.showToast(activity, "连接超时，通话已结束", Toast.LENGTH_LONG)
                        closeAll()
                    }
                }

                AUTO_HANGUP -> {
                    // 2分钟自动挂断
                    if (activity.videoIsPlaying) {
                        ELog.showToast(activity, "通话时间已到，通话已结束", Toast.LENGTH_LONG)
                        closeAll()
                    }
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_video_call)
        EventBus.getDefault().register(this)
        devId = intent.getStringExtra("devId")!!
        channelId = intent.getIntExtra("channelId", -1)
        initData()
        initView()
        // 启动30秒连接超时计时器
        mHandler.sendEmptyMessageDelayed(CONNECTION_TIMEOUT, 30000)
    }

    override fun initView() {
        surfaceView = findViewById(R.id.surfaceview)
        textureView = findViewById(R.id.surfaceview_video)
        frRoot = findViewById(R.id.fr_root)
        loadingLayout = findViewById(R.id.loading_layout) // 假设布局中有loading_layout
        controlPanel = findViewById(R.id.control_panel) // 假设布局中有control_panel

        // 初始化时显示加载框，隐藏控制按钮
        showLoading()

        // 初始化SurfaceView
        surfaceHolder = surfaceView.holder
        surfaceHolder!!.addCallback(this@VideoCallActivity)

        // 初始化绘制工具
        paint = Paint().apply {
            isAntiAlias = true
            isFilterBitmap = true
            isDither = true
        }
        matrix = Matrix()

        // 设置TextureView的旋转
        textureView.rotation = degree

        // 添加布局变化监听，实时计算显示区域
        frRoot.viewTreeObserver.addOnGlobalLayoutListener {
            calculateDisplaySize()
        }
    }

    /**
     * 显示加载状态（隐藏按钮，显示加载框）
     */
    private fun showLoading() {
        loadingLayout.visibility = View.VISIBLE
        controlPanel.visibility = View.GONE
    }

    /**
     * 显示控制按钮（隐藏加载框，显示按钮）
     */
    private fun showControls() {
        loadingLayout.visibility = View.GONE
        controlPanel.visibility = View.VISIBLE
    }

    override fun initData() {
        devDao = BaseAppApplication.instance!!.getYkDao(this)
        shaowDao = BaseAppApplication.instance!!.getShaowDao(this)
        userName = preference.getString(Config.EQUES_USER_NAME)!!

        CoroutineScope(Dispatchers.IO).launch {
            Log.e(TAG, "userName:$userName")
            devInfo = devDao.getBdyListEntry(userName, devId)
            Log.e(TAG, "devInfo: $devInfo")

            devInfo?.let {
                devRole = it.role
                uid = it.uid
                devState = it.stat
            }
            setState()
            setVideoSize()
            Log.e(TAG, "devRole:$devRole")

            val shaowList = shaowDao.getShaowEntry(userName, devId)
            shaowList?.let {
                val cameraId = shaowList.camera_id
                degree = getDegree(cameraId.toInt()).toFloat()
            }
        }
    }

    private fun setVideoSize() {
        // 根据设备类型设置视频源尺寸
        when (devRole) {
            BuddyType.TYPE_WIFI_DOOR_VL4, BuddyType.TYPE_WIFI_DOOR_VM2C -> {
                videoWidth = 320f
                videoHeight = 480f
            }
            else -> {
                videoWidth = 480f
                videoHeight = 864f
            }
        }
    }

    private fun calculateDisplaySize() {
        // 获取显示区域的实际尺寸
        displayWidth = frRoot.width.toFloat()
        displayHeight = frRoot.height.toFloat()

        Log.d(TAG, "Display size: $displayWidth x $displayHeight")
        Log.d(TAG, "Video source size: $videoWidth x $videoHeight")

        // 计算缩放比例和居中偏移量
        calculateScaleAndOffset(degree)
    }

    private fun calculateScaleAndOffset(rotation: Float = 0f) {
        if (displayWidth <= 0 || displayHeight <= 0) return

        // 根据旋转角度调整视频尺寸（90/270度时交换宽高）
        val (adjustedVideoWidth, adjustedVideoHeight) = when (rotation) {
            90f, 270f -> videoHeight to videoWidth
            else -> videoWidth to videoHeight // 0, 180度保持原样
        }

        // 计算宽高比
        val videoAspect = adjustedVideoWidth / adjustedVideoHeight
        val displayAspect = displayWidth / displayHeight

        // 根据宽高比计算缩放后的尺寸
        scaledWidth = if (videoAspect > displayAspect) {
            displayWidth
        } else {
            displayHeight * videoAspect
        }
        scaledHeight = if (videoAspect > displayAspect) {
            displayWidth / videoAspect
        } else {
            displayHeight
        }

        // 计算居中偏移量
        offsetX = (displayWidth - scaledWidth) / 2
        offsetY = (displayHeight - scaledHeight) / 2

        Log.d(TAG, "Rotation: $rotation°, Video: ${adjustedVideoWidth}x${adjustedVideoHeight}")
        Log.d(TAG, "Display: ${displayWidth}x${displayHeight}, Scaled: ${scaledWidth}x${scaledHeight}")
        Log.d(TAG, "Offset: $offsetX, $offsetY")
    }

    private fun setState() {
        devState = when (devState) {
            Config.DEVICE_SLEEP -> {
                online = true
                isWakeUp = true
                Config.DEVICE_SLEEP
            }
            Config.DEVICE_ONLINE -> {
                online = true
                isWakeUp = false
                Config.DEVICE_ONLINE
            }
            else -> {
                online = false
                isWakeUp = false
                devState
            }
        }
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        if (surfaceThread == null) {
            surfaceThread = SurfaceThread()
        }

        mHandler.postDelayed({
            ELog.d(TAG, "当前App doorBellService... $doorBellService")
            doorBellService?.setImgDataListener(this)
            mCreateHolder = holder

            if (DoorBellService.icvss?.equesIsLogin() != true) {
                ELog.d(TAG, "当前App已经掉线正在重新登录...")
                doorBellService?.login(DoorBellService.MSG_ONCLICK_LOGIN)
            } else {
                ELog.d(TAG, "当前App在线正在执行呼叫流程...")
                setVideoState()
            }
        }, 1000)
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        mCreateHolder = holder
        // 重新计算显示尺寸
        calculateDisplaySize()
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        mCreateHolder = holder
        isHangUp = true
        surfaceThread?.interrupt()
    }

    private fun setVideoState() {
        if (online && !isWakeUp) {
            videoCallOpen()
        } else {
            wakeUp()
        }
    }

    private fun wakeUp() {
        mHandler.sendEmptyMessage(REQUEST_AWAKEN)
    }

    private fun videoCallOpen() {
        isWakeUp = false
        if (!isHasCall) {
            ELog.d(TAG, "DoorBellService is login start call open...")
            ELog.d(TAG, "IOT setSurface... $channelId")

            if (channelId >= 0) {
                isHasCall = true
                // 门铃接听
                DoorBellService.icvss?.iot?.setSurface(devRole, channelId, mCreateHolder!!.surface)
            } else {
                DoorBellService.icvss?.iot?.call(
                    devRole, uid, 864, 480, false, 0, 0, 0, 0
                )
            }
        }
    }

    override fun imgData(bytes: ByteArray?, len: Int) {
        if (isHangUp || bytes == null || len <= 0) return

        if (!videoIsPlaying) {
            mHandler.sendEmptyMessage(FIRST_FRAME_COME)
        }

        if (mjpeg == null) {
            mjpeg = Mjpeg(bytes, len, false)
        } else {
            mjpeg!!.bytes = bytes
            mjpeg!!.len = len
            mjpeg!!.isDraw = false
        }

        startDrawingThread()
    }

    override fun bitmapData(data: Bitmap?) {
        if (isHangUp || data == null) return

        if (!videoIsPlaying) {
            mHandler.sendEmptyMessage(FIRST_FRAME_COME)
        }

        isBitmapData = true
        if (mjpeg == null) {
            mjpeg = Mjpeg(false, data)
        } else {
            // 回收之前的bitmap
            mjpeg!!.bitmap?.recycle()
            mjpeg!!.bitmap = data
            mjpeg!!.isDraw = false
        }

        startDrawingThread()
    }

    private fun startDrawingThread() {
        if (surfaceThread?.isAlive != true) {
            surfaceThread?.interrupt()
            surfaceThread = SurfaceThread()
            surfaceThread!!.start()
        }
    }

    override fun firFrameCome() {
        // 第一帧到达回调
    }

    /**
     * 图片绘制线程
     */
    inner class SurfaceThread : Thread() {
        override fun run() {
            super.run()
            while (isRunDraw && !isInterrupted) {
                if (mjpeg?.isDraw == false) {
                    try {
                        if (isBitmapData) {
                            refreshBitmap(mjpeg!!.bitmap)
                        } else {
                            refreshMJPEG(mjpeg!!.bytes, mjpeg!!.len)
                        }
                        mjpeg!!.isDraw = true
                    } catch (e: Exception) {
                        Log.e(TAG, "Drawing error: ${e.message}")
                    }
                }
                // 降低CPU占用
                try {
                    Thread.sleep(16) // ~60fps
                } catch (e: InterruptedException) {
                    break
                }
            }
        }
    }

    /**
     * 刷新MJPEG数据 - 使用SurfaceView绘制
     */
    private fun refreshMJPEG(bytes: ByteArray?, len: Int) {
        if (bytes == null || len <= 0 || len > bytes.size) return

        var bitmap: Bitmap? = null
        try {
            bitmap = BitmapFactory.decodeByteArray(bytes, 0, len)
            bitmap?.let {
                drawBitmapToSurface(it)
                drawBitmapToTexture(it)
            }
        } catch (e: Exception) {
            Log.e(TAG, "MJPEG decode error: ${e.message}")
        } finally {
            bitmap?.recycle()
        }
    }

    /**
     * 刷新Bitmap数据
     */
    private fun refreshBitmap(bitmap: Bitmap?) {
        bitmap?.let {
            drawBitmapToSurface(it)
            drawBitmapToTexture(it)
        }
    }

    /**
     * 绘制Bitmap到SurfaceView（居中缩放显示）
     */
    private fun drawBitmapToSurface(bitmap: Bitmap) {
        if (bitmap.isRecycled || mCreateHolder == null) return

        var canvas: Canvas? = null
        try {
            canvas = mCreateHolder!!.lockCanvas()
            canvas?.let {
                // 清空画布
                it.drawColor(0xFF000000.toInt())

                // 创建目标矩形（居中显示）
                val destRect = RectF(offsetX, offsetY, offsetX + scaledWidth, offsetY + scaledHeight)

                // 绘制图片（自动缩放并居中）
                it.drawBitmap(bitmap, null, destRect, paint)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Draw bitmap to surface error: ${e.message}")
        } finally {
            if (canvas != null) {
                mCreateHolder!!.unlockCanvasAndPost(canvas)
            }
        }
    }

    /**
     * 绘制Bitmap到TextureView（居中缩放显示）
     */
    private fun drawBitmapToTexture(bitmap: Bitmap) {
        if (bitmap.isRecycled) return

        val canvas = textureView.lockCanvas() ?: return

        try {
            // 清空画布
            canvas.drawColor(0xFF000000.toInt())

            // 创建目标矩形（居中显示）
            val destRect = RectF(offsetX, offsetY, offsetX + scaledWidth, offsetY + scaledHeight)

            // 绘制图片（自动缩放并居中）
            canvas.drawBitmap(bitmap, null, destRect, paint)
        } catch (e: Exception) {
            Log.e(TAG, "Draw bitmap to texture error: ${e.message}")
        } finally {
            textureView.unlockCanvasAndPost(canvas)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onRefreshEvent(event: EventTotalThread) {
        when (event.refresh) {
            234 -> {
                ELog.e(TAG, "底层挂断......")
                closeAll()
            }

            235 -> {
                // 设备通道建立 适配画面
                channelId = event.intMsg
                videoCallOpen()
            }

            Config.EVENT_DEVICE_LIST_REFRESH -> {
                // 列表刷新
                if (!StringUtils.isEmpty(devId) && devId == event.stringMsg) {
                    devState = event.intMsg
                    if (!videoIsPlaying && devState == Config.DEVICE_ONLINE) {
                        mHandler.removeMessages(REQUEST_AWAKEN)
                        setState()
                        videoCallOpen()
                    }
                }
            }
        }
    }

    override fun onBackPressed() {
        super.onBackPressed()
        mHandler.sendEmptyMessage(CLOSE_VIDEO)
    }

    override fun onDestroy() {
        isRunDraw = false
        isHangUp = true
        surfaceThread?.interrupt()
        surfaceThread = null
        // 清理资源
        mjpeg?.bitmap?.recycle()
        mjpeg = null
        mCreateHolder?.removeCallback(this)
        closeAll()
        EventBus.getDefault().unregister(this)
        mHandler.removeCallbacksAndMessages(null)

        super.onDestroy()
    }

    /**
     * 关闭所有通话和视频播放相关资源
     */
    private fun closeAll() {
        if (!isHangUp) {
            isHangUp = true
            ELog.e(TAG, "closeAll().....")
            videoIsPlaying = false
            isHasCall = false

            Executors.newSingleThreadExecutor().submit {
                DoorBellService.icvss?.iot?.closeAllCall()
            }
            finish()
        }
    }

    fun onViewClicked(view: View) {
        when (view.id) {
            R.id.btn_exit -> {
                Toast.makeText(this, "结束通话", Toast.LENGTH_SHORT).show()
                closeAll()
                finish()
            }
            R.id.btn_mic -> {
                isRecordAudio = !isRecordAudio
                DoorBellService.icvss?.iot?.audioRecordEnable(isRecordAudio)
            }
            R.id.btn_speak -> {
                isPlayAudio = !isPlayAudio
                DoorBellService.icvss?.iot?.audioPlayEnable(isPlayAudio)
            }
        }
    }

    /**
     * 根据摄像头ID获取旋转角度
     */
    private fun getDegree(cameraId: Int): Int {
        return when (cameraId) {
            0 -> 90
            4 -> 180
            3 -> 90
            5 -> 0
            else -> -90
        }
    }
}
